package com.icesoft.generation.controller;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import com.icesoft.framework.core.controller.BaseCrudRestController;
import com.icesoft.framework.core.vo.JsonResult;
import com.icesoft.framework.core.vo.Pagination;
import com.icesoft.generation.entity.GenDtoField;
import com.icesoft.generation.entity.GenField;
import com.icesoft.generation.entity.GenTable;
import com.icesoft.generation.entity.GenVoField;
import com.icesoft.generation.helper.TableFieldFormatterHelper;
import com.icesoft.generation.service.impl.GenFieldDtoServiceImpl;
import com.icesoft.generation.service.impl.GenFieldServiceImpl;
import com.icesoft.generation.service.impl.GenFieldVoServiceImpl;
import com.icesoft.generation.service.impl.GenTableServiceImpl;
import com.icesoft.generation.vo.GenDtoFieldVO;
import com.icesoft.generation.vo.GenFieldVO;
import com.icesoft.generation.vo.GenTableVO;
import com.icesoft.generation.vo.GenVoFieldVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.List;
import java.util.Map;

@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/gen/table")
public class GenTableController extends BaseCrudRestController<GenTable> {

	private final GenTableServiceImpl genTableService;

	private final GenFieldServiceImpl fieldService;

	private final GenFieldDtoServiceImpl fieldDtoService;

	private final GenFieldVoServiceImpl fieldVoService;

	@GetMapping("/getZip")
	public ResponseEntity<ByteArrayResource> getZip(Long id) throws IOException {
		byte[] data = genTableService.getZip(id);
		ByteArrayResource resource = new ByteArrayResource(data);
		return ResponseEntity.ok()
				.header(HttpHeaders.CONTENT_DISPOSITION)
				.contentType(MediaType.APPLICATION_OCTET_STREAM)
				.contentLength(data.length)
				.body(resource);
	}

	@GetMapping("/getVueZip")
	public ResponseEntity<ByteArrayResource> getVueZip( Long id) throws IOException {
		byte[] data = genTableService.getVueZip(id);
		ByteArrayResource resource = new ByteArrayResource(data);
		return ResponseEntity.ok()
				.header(HttpHeaders.CONTENT_DISPOSITION)
				.contentType(MediaType.APPLICATION_OCTET_STREAM)
				.contentLength(data.length)
				.body(resource);
	}

	@GetMapping("/preview/{id}")
	public JsonResult<?> preview(@PathVariable("id") Long id) throws Exception {
		return JsonResult.OK(genTableService.preview(id));
	}

	@GetMapping("/genVueCode/{id}")
	public JsonResult<?> genVueCode(@PathVariable("id") Long id) throws Exception {
		genTableService.generatorVueCode(id);
		return JsonResult.OK();
	}

	@GetMapping("/genCode/{id}")
	public JsonResult<?> genCode(@PathVariable("id") Long id) throws Exception {
		genTableService.generatorCode(id);
		return JsonResult.OK();
	}

	/**
	 * 查询ViewObject的分页数据
	 * <p>
	 * url请求参数示例: /list?field=abc&pageSize=20&pageIndex=1&orderBy=id
	 * </p>
	 */
	@GetMapping("/query")
	public JsonResult<List<GenTable>> getViewObjectListMapping(GenTable entity, Pagination pagination) throws Exception {
		return super.getViewObjectList(entity, pagination, GenTable.class);
	}

	/**
	 * 根据资源id查询ViewObject
	 */
	@GetMapping("/{id}")
	public JsonResult<GenTableVO> getViewObjectMapping(@PathVariable("id") Long id) throws Exception {
		return super.getViewObject(id, GenTableVO.class);
	}

	/**
	 * 新建
	 */
	@PostMapping("/create")
	public JsonResult<Map<String, Object>> createEntityMapping(@Valid @RequestBody GenTableVO dto) throws Exception {
		JsonResult<Map<String, Object>> jsonResult = super.createEntity(dto);
		Map<String, Object> data = jsonResult.getData();
		Long tableId = Long.parseLong(String.valueOf(data.get("id")));
		if (dto.getFields() != null) {
			for (GenFieldVO field : dto.getFields()) {
				field.setCommentName(TableFieldFormatterHelper.camelToUnderline(field.getName()));
				field.setTableId(tableId);
				fieldService.createEntity(field);
			}
		}
		if (dto.getDtoFields() != null) {
			for (GenDtoFieldVO field : dto.getDtoFields()) {
				field.setTableId(tableId);
				fieldDtoService.createEntity(field);
			}
		}
		if (dto.getVoFields() != null) {
			for (GenVoFieldVO field : dto.getVoFields()) {
				field.setTableId(tableId);
				fieldVoService.createEntity(field);
			}
		}
		return jsonResult;
	}

	/**
	 * 更新
	 */
	@PostMapping("/update/{id}")
	public JsonResult<?> updateEntityMapping(@PathVariable("id") Long id, @Valid @RequestBody GenTableVO entityOrDto) throws Exception {
		JsonResult<?> jsonResult = super.updateEntity(id, entityOrDto);
		if (fieldService.lambdaQuery().eq(GenField::getTableId, id).count() > 0) {
			List<GenField> list = fieldService.lambdaQuery().eq(GenField::getTableId, id).list();
			for (GenField genField : list) {
				fieldService.deleteEntity(genField.getId());
			}
		}
		if (fieldDtoService.lambdaQuery().eq(GenDtoField::getTableId, id).count() > 0) {
			List<GenDtoField> list = fieldDtoService.lambdaQuery().eq(GenDtoField::getTableId, id).list();
			for (GenDtoField genField : list) {
				fieldDtoService.deleteEntity(genField.getId());
			}
		}
		if (fieldVoService.lambdaQuery().eq(GenVoField::getTableId, id).count() > 0) {
			List<GenVoField> list = fieldVoService.lambdaQuery().eq(GenVoField::getTableId, id).list();
			for (GenVoField genVoField : list) {
				fieldVoService.deleteEntity(genVoField.getId());
			}
		}

		if (entityOrDto.getFields() != null) {
			for (GenFieldVO field : entityOrDto.getFields()) {
				field.setCommentName(TableFieldFormatterHelper.camelToUnderline(field.getName()));
				field.setTableId(id);
				fieldService.createEntity(field);
			}
		}
		if (entityOrDto.getDtoFields() != null) {
			for (GenDtoFieldVO field : entityOrDto.getDtoFields()) {
				field.setTableId(id);
				fieldDtoService.createEntity(field);
			}
		}
		if (entityOrDto.getVoFields() != null) {
			for (GenVoFieldVO field : entityOrDto.getVoFields()) {
				field.setTableId(id);
				fieldVoService.createEntity(field);
			}
		}
		return jsonResult;
	}

	/**
	 * 根据id删除资源对象
	 */
	@GetMapping("/delete/{id}")
	public JsonResult<?> deleteEntityMapping(@PathVariable("id") Long id) throws Exception {
		if (fieldService.lambdaQuery().eq(GenField::getTableId, id).count() > 0) {
			List<GenField> list = fieldService.lambdaQuery().eq(GenField::getTableId, id).list();
			for (GenField genField : list) {
				fieldService.deleteEntity(genField.getId());
			}
		}
		if (fieldDtoService.lambdaQuery().eq(GenDtoField::getTableId, id).count() > 0) {
			List<GenDtoField> list = fieldDtoService.lambdaQuery().eq(GenDtoField::getTableId, id).list();
			for (GenDtoField genField : list) {
				fieldDtoService.deleteEntity(genField.getId());
			}
		}
		if (fieldVoService.lambdaQuery().eq(GenVoField::getTableId, id).count() > 0) {
			List<GenVoField> list = fieldVoService.lambdaQuery().eq(GenVoField::getTableId, id).list();
			for (GenVoField genVoField : list) {
				fieldVoService.deleteEntity(genVoField.getId());
			}
		}
		return super.deleteEntity(id);
	}

}
